

// packaged_task的使用
#include <iostream>
#include <future>
#include <memory>

int Add(int num1, int num2)
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "开始执行！" << std::endl;
    int resul = num1 + num2;
    return resul;
}

int main()
{
    // 可以通过packaged_task对象交给智能指针来管理，也就是封装成一个指针
    // 然后将该指针传入线程中，再解引用执行
    // 但是此时的packaged_task对象就需要从堆上new一个，而不是在栈上开辟
    // 因为线程的执行顺序不确定，可能packaged_task对象销毁了，才会执行线程函数
    //  std::shared_ptr<std::packaged_task<int(int, int)>> ptask(new std::packaged_task<int(int, int)>(Add));
    auto ptask = std::make_shared<std::packaged_task<int(int, int)>>(Add);
    std::thread thr([ptask]()
                    {
    std::this_thread::sleep_for(std::chrono::seconds(3));

        (*ptask)(11,22); });
    std::future<int> fut = ptask->get_future();
    int ret = fut.get(); // 同样会在这里阻塞
    std::cout << ret << std::endl;
    thr.join();

    // ————————————————————————————————————————————————————————————————————————————————————
    //  定义一个packaged_task对象，它可以用来管理一个可调用对象
    //   std::packaged_task<int(int,int)> task(Add);
    //   std::future<int> fut=task.get_future();
    //  //可以把该对象当作使一个可调用对象来执行
    //  task(11,22);
    //  int ret=fut.get();
    //  std::cout<<ret<<std::endl;

    // ——————————————————————————————————————————————————————————————————————————————————
    //  不能将task对象传入async，让异步线程去执行
    //   std::packaged_task<int(int,int)> task(Add);
    //   std::future<int> fut=task.get_future();
    //   std::async(std::launch::async,task,11,22);
    //   std::cout<<fut.get()<<std::endl;

    // ——————————————————————————————————————————————————————————————————————————————————
    // 也不能将task对象作为线程的入口函数
    //  std::packaged_task<int(int,int)> task(Add);
    //  std::future<int> fut=task.get_future();
    //  std::thread thr(task,11,22);
    //  std::cout<<fut.get()<<std::endl;
    //  thr.join();

    return 0;
}